package com.gxa.learning.pc.controller;

import com.gxa.learning.core.common.ExceptionCode;
import com.gxa.learning.core.common.JsonResult;
import com.gxa.learning.core.exception.BusinessException;
import com.gxa.learning.core.pojo.*;
import com.gxa.learning.core.util.CommentTreeUtil;
import com.gxa.learning.core.util.JsonUtil;
import com.gxa.learning.core.util.MD5Util;
import com.gxa.learning.core.util.StringUtil;
import com.gxa.learning.pc.mapper.UserMapper;
import com.gxa.learning.pc.service.LevelManagerService;
import com.gxa.learning.pc.service.MainService;
import com.gxa.learning.pc.service.TypeService;
import com.gxa.learning.pc.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 我的主页
 *
 * @author YXQ
 * @date 2021/12/8 16:43
 */
@RestController
@RequestMapping("/home")
@Api(tags = "我的主页的接口")
public class MainController {

    @Autowired
    MainService mainService;

    @Autowired
    UserService userService;

    @Autowired
    LevelManagerService levelManagerService;

    @Autowired
    TypeService typeService;

    @GetMapping("/getHotCourse")
    @ApiOperation("热门课程的接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户的id", dataType = "long", paramType = "query")
    })
    public Map<String, Object> hotCourse(Long userId) {
        // 查询前16门的热门课程
        List<CourseForMain> hotCourseByScore = mainService.getHotCourseByScore(0L, 16L);
        // 遍历热门课程
        for (CourseForMain courseForMain : hotCourseByScore) {
            // 获取这门课程得id值
            Long id = courseForMain.getId();
            // 默认表示该用户没有收藏过了该课程
            courseForMain.setIsLove(0);
            // 根据当前id获取用户的收藏的课程
            List<Course> loveCourses = mainService.getLoveCourse(userId);
            // 遍历收藏的课程
            for (Course loveCourse : loveCourses) {
                // 获取用户收藏过的课程的id
                Long loveId = loveCourse.getId();
                // 如果课程id与收藏的课程的id相同，设置课程收藏状态为1
                if (loveId.equals(id)) {
                    // 表示该用户已经收藏过了该课程
                    courseForMain.setIsLove(1);
                }
            }
        }
        // 生成给前端返回的数据
        JsonResult jsonResult = new JsonResult();
        // 设置返回的数据
        jsonResult.setCode("1");
        jsonResult.setMsg("查询成功");
        jsonResult.setData(hotCourseByScore);
        // 返回给前端
        return jsonResult.getDataMap();
    }

    @GetMapping("/loveCourse")
    @ApiOperation("收藏/取消收藏 课程的接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户的id", dataType = "long", paramType = "query"),
            @ApiImplicitParam(name = "courseId", value = "课程的id", dataType = "long", paramType = "query"),
            @ApiImplicitParam(name = "love", value = "是否收藏1收藏0不收藏 ", dataType = "int", paramType = "query"),
    })
    public Map<String, Object> loveCourse(Long userId, Long courseId, Integer love) throws BusinessException {
        // 调用收藏课程的方法
        mainService.loveCourse(userId, courseId, love);
        // 生成给前端返回的数据
        JsonResult jsonResult = new JsonResult();
        // 设置返回的数据
        jsonResult.setCode("1");
        jsonResult.setMsg("操作成功");
        // 返回给前端
        return jsonResult.getDataMap();
    }

    @GetMapping("/getLoveCourse")
    @ApiOperation("查看我的收藏的接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户的id", dataType = "long", paramType = "query")
    })
    public Map<String, Object> getLoveCourse(Long userId) {
        // 调用收藏课程的方法
        List<Course> loveCourse = mainService.getLoveCourse(userId);
        // 获取收藏的课程的列表
        List<CourseForMain> myLoveCourse = getLikeCourse(userId);
        // 生成给前端返回的数据
        JsonResult jsonResult = new JsonResult();
        // 设置返回的数据
        jsonResult.setCode("1");
        jsonResult.setMsg("查询成功");
        jsonResult.setData(myLoveCourse);
        jsonResult.put("count", loveCourse.size());
        // 返回给前端
        return jsonResult.getDataMap();
    }

    @GetMapping("/selectLoveCourse")
    @ApiOperation("搜索我的收藏的接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户的id", dataType = "long", paramType = "query"),
            @ApiImplicitParam(name = "typeName", value = "课程的类型", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "courseName", value = "课程的名字", dataType = "string", paramType = "query"),
    })
    public Map<String, Object> selectLoveCourse(Long userId, String typeName, String courseName) {
        // 调用收藏课程的方法
        List<Course> loveCourse = mainService.getLoveCourse(userId);
        // 获取收藏的课程的列表
        List<CourseForMain> myLoveCourse = getLikeCourse(userId);
        // 生成一个查询结果的课程的列表
        List<CourseForMain> newMyLoveCourse = new ArrayList<>();
        // 根据从缓存中获取的收藏的课程做
        for (CourseForMain courseForMain : myLoveCourse) {
            // 根据条件组合搜索情况
            if (StringUtil.isEmpty(typeName) && StringUtil.isEmpty(courseName)) {
                // 都为空，就直接全部加进去
                newMyLoveCourse.add(courseForMain);
            } else if (StringUtil.isEmpty(typeName) && !StringUtil.isEmpty(courseName)) {
                // 获取结果中的标题来做模糊
                String title = courseForMain.getTitle();
                // 通过判断包含做模糊查询
                if (title.contains(courseName)) {
                    // 满足条件加载到数据库中
                    newMyLoveCourse.add(courseForMain);
                }
            } else if (!StringUtil.isEmpty(typeName) && StringUtil.isEmpty(courseName)) {
                // 获取结果中的类型名字做相等查询
                String type = courseForMain.getType();
                // 通过判断包含做相等查询
                if (type.equals(typeName)) {
                    // 满足条件加载到数据库中
                    newMyLoveCourse.add(courseForMain);
                }
            } else if (!StringUtil.isEmpty(typeName) && !StringUtil.isEmpty(courseName)) {
                // 获取结果中的标题来做模糊
                String title = courseForMain.getTitle();
                // 获取结果中的类型名字做相等查询
                String type = courseForMain.getType();
                // 通过判断包含做模糊查询
                if (title.contains(courseName) && type.equals(typeName)) {
                    // 满足条件加载到数据库中
                    newMyLoveCourse.add(courseForMain);
                }
            }
        }
        // 生成给前端返回的数据
        JsonResult jsonResult = new JsonResult();
        // 设置返回的数据
        jsonResult.setCode("1");
        jsonResult.setMsg("查询成功");
        jsonResult.setData(newMyLoveCourse);
        jsonResult.put("count", newMyLoveCourse.size());
        // 返回给前端
        return jsonResult.getDataMap();
    }

    public List<CourseForMain> getLikeCourse(Long userId) {
        // 调用收藏课程的方法
        List<Course> loveCourse = mainService.getLoveCourse(userId);
        // 生成给前端返回的集合
        List<CourseForMain> myLoveCourse = new ArrayList<>();
        // 遍历并赋值
        for (Course course : loveCourse) {
            // 将数组转移到新的对象上，主要是将等级和类型转成字符串反给前端
            CourseForMain courseForMain = new CourseForMain();
            courseForMain.setId(course.getId());
            courseForMain.setExplain(course.getExplain());
            courseForMain.setCover(course.getCover());
            // 根据课程的等级id查询等级id
            Long lmId = course.getLmId();
            LevelManager levelManager = levelManagerService.selectById(lmId);
            courseForMain.setLevel(levelManager.getLevel());
            // 根绝课程的类型id查询等级id
            Long typeId = course.getTypeId();
            Type type = typeService.selectById(typeId);
            courseForMain.setType(type.getName());
            courseForMain.setTitle(course.getTitle());
            courseForMain.setIsLove(1);
            // 根据条件做出判断
            // 将类型转化后存集合中
            myLoveCourse.add(courseForMain);
        }
        return myLoveCourse;
    }

    @SneakyThrows
    @PostMapping("/updateUserInfo")
    @ApiOperation("修改用户基本信息的接口")
    public Map<String, Object> updateUserInfo(@RequestBody User user) {
        // 拿到邮箱做校验
        String email = user.getEmail();
        // 拿到手机做校验
        String phone = user.getPhone();
        if (StringUtil.isEmpty(email) || !StringUtil.isEmail(email)) {
            // 不是一个有效的邮箱
            throw new BusinessException(ExceptionCode.NOT_TRUE_EMAIL);
        }
        if (StringUtil.isEmpty(phone) || !StringUtil.isPhoneNumber(phone)) {
            // 不是一个有效的手机号
            throw new BusinessException(ExceptionCode.NOT_TRUE_PHONE);
        }
        // 判断新改的手机号是否已经被注册过了
        User user1 = userService.selectByPhone(phone);
        if (!user.getId().equals(user1.getId())){
            throw new BusinessException(ExceptionCode.HAS_PHONE);
        }else {
            user.setPhone(null);
        }

        // 更新
        Integer integer = userService.updateById(user);

        System.out.println("更新: " + integer);
        // 查找修改后的用户信息
        User user2 = userService.selectByPhone(phone);
        //
        if (user2 != null) {
            // 如果用户的头像是为空
            if (StringUtil.isEmpty(user2.getPhoto())) {
                // 设置头像字符串为空串
                user2.setPhoto("");
            }
        }
        System.out.println(phone);
        // 生成给前端返回的数据
        JsonResult jsonResult = new JsonResult();
        // 设置返回的数据
        jsonResult.setCode("1");
        jsonResult.setMsg("修改成功");
        jsonResult.setData(user2);
        // 返回给前端
        return jsonResult.getDataMap();
    }

    @SneakyThrows
    @PostMapping("/updateUserPassword")
    @ApiOperation("修改用户密码的接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "userId", dataType = "Long", paramType = "query")
    })
    public Map<String, Object> updateUserPassword(Long userId, String oldPassword, String newPassword, String confirmPassword) {
        User user = userService.selectById(userId);
        //如果老密码输入正确才进行下面的操作，否则抛异常

        //获取盐
        String salt = user.getSalt();
        //获取真正的旧密码
        String oldPwd = user.getPassword();
        //获取真正输入的密码
        String newPwd = MD5Util.encode(oldPassword + salt);
        //要求输入的两次新密码要一致,否则抛异常
        if (oldPwd.equals(newPwd)) {
            //如果新密码和确认密码一致，可以修改
            if (newPassword.equals(confirmPassword)) {
                user.setPassword(MD5Util.encode(newPassword + salt));
                userService.updateById(user);
            } else {
                throw new BusinessException(ExceptionCode.NO_REPEDPWD);
            }
        } else {
            throw new BusinessException(ExceptionCode.ERORR_PWD);
        }

        ////////
        // 生成给前端返回的数据
        JsonResult jsonResult = new JsonResult();
        // 设置返回的数据
        jsonResult.setCode("1");
        jsonResult.setMsg("修改成功");
        // 返回给前端
        return jsonResult.getDataMap();
    }

    @GetMapping("/comment")
    @ApiOperation("评论与回复的接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "userId: 当前评论用户的id", dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "courseId", value = "courseId: 评论的课程的id", dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "remark", value = "remark: 评论的内容", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "pId", value = "pId: 直接评论->pId为0,回复->pid为一级评论的编号", dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "reply", value = "reply: 被回复的人", dataType = "string", paramType = "query")
    })
    public Map<String, Object> comment(Long userId, Long courseId, String remark, Long pId, String reply) {
        mainService.comment(userId, courseId, remark, pId, reply);
        JsonResult jsonResult = new JsonResult();
        // 设置返回的数据
        jsonResult.setCode("1");
        jsonResult.setMsg("评论发布成功");
        // 返回给前端
        return jsonResult.getDataMap();
    }

    @GetMapping("/likeComment")
    @ApiOperation("点赞评论与回复的接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "userId: 当前评论用户的id", dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "courseId", value = "courseId: 当前课程的id", dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "remarkId", value = "remarkId: 点赞的评论的id", dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "isLike", value = "isLike: 是否点赞 1点赞 0取消点赞", dataType = "Integer", paramType = "query")
    })
    public Map<String, Object> likeComment(Long userId, Long courseId, Long remarkId, Integer isLike) {
        mainService.likeComment(userId, courseId, remarkId, isLike);
        JsonResult jsonResult = new JsonResult();
        // 设置返回的数据
        jsonResult.setCode("1");
        jsonResult.setMsg("操作成功");
        // 返回给前端
        return jsonResult.getDataMap();
    }

    @GetMapping("/getCommentList")
    @ApiOperation("获取评论与回复的列表的接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "userId: 当前评论用户的id", dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "courseId", value = "courseId: 当前课程的id", dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "page", value = "page: 页码", dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "size", value = "size: 每页的记录数", dataType = "int", paramType = "query")
    })
    public Map<String, Object> getCommentList(Long userId, Long courseId, Integer page, Integer size) {
        // 需要给前端的数据，用户编号，用户头像，用户发表评论的时间，评论的内容，点赞，谁回复了谁
        // 一级，二级
        List<CommentVo> commentList = mainService.getCommentList(userId, courseId);
        // 将拿到的集合转成树状结构
        List<CommentVo> oneMenu = CommentTreeUtil.getOneMenu(commentList);
        int size1 = oneMenu.size();
        // 给前端返回的数据
        List<CommentVo> newOneMenu = new ArrayList<>(3);
        // 给前端的返回数据
        JsonResult jsonResult = new JsonResult();
        // 分页
        if (page != null && !TrainPlanController.ZERO.equals(page)) {
            if (size != null && !TrainPlanController.ZERO.equals(size)) {
                // page和size都不为null或者0时
                if (size1 == 0) {
                    jsonResult.setData(oneMenu);
                } else {
                    // 遍历总的结果集，把分页的部分数据传入分页后的集合
                    for (int i = 0; i < size; i++) {
                        if ((page - 1) * size + i >= size1) {
                            break;
                        }
                        // 从(page - 1) * size开始的size或者小于size条数据装入新的集合中
                        newOneMenu.add(oneMenu.get((page - 1) * size + i));
                    }
                    // 传给前端
                    jsonResult.setData(newOneMenu);
                }
            }
        } else {
            jsonResult.setData(oneMenu);
        }
        // 设置返回的数据
        jsonResult.setCode("1");
        jsonResult.setMsg("获取列表成功");
        jsonResult.put("count", oneMenu.size());
        // 返回给前端
        return jsonResult.getDataMap();
    }


}
